package com.hsogoo.study.concurrency;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.junit.Test;

public class ConditionProducerAndConsumerTest {

    private int productCount;
    private Lock lock = new ReentrantLock();
    private Condition producerCondition = lock.newCondition();
    private Condition consumerCondition = lock.newCondition();
    private int produceCount;
    private int consumeCount;

    public void produce() throws InterruptedException {
        try{
            lock.lock();
            System.out.printf("productCount=" + productCount);
            if(productCount > 0){
                producerCondition.await();
            }
            productCount++;
            System.out.println("======produce:" + ++produceCount);
            consumerCondition.signal();
        }finally {
            lock.unlock();
        }
    }

    public void consume() throws InterruptedException{
        try{
            lock.lock();
            System.out.printf("productCount=" + productCount);
            if(productCount < 1){
                consumerCondition.await();
            }
            productCount--;
            System.out.println("======consume:" + ++consumeCount);
            producerCondition.signal();
        }finally {
            lock.unlock();
        }
    }

    /**
     * 生产者线程
     */
    public class ProducerThread implements Runnable{
        //生产100个商品
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                try {
                    produce();
                } catch (InterruptedException e) {
                }
            }
        }
    }

    /**
     * 消费者线程
     */
    public class ConsumerThread implements Runnable{
        //消费100个商品
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                try {
                    consume();
                } catch (InterruptedException e) {
                }
            }
        }
    }

    @Test
    public void testProduceAndConsume() throws InterruptedException {
        ConditionProducerAndConsumerTest test = new ConditionProducerAndConsumerTest();
        Thread p = new Thread(test.new ProducerThread());
        Thread c = new Thread(test.new ConsumerThread());
        p.start();
        c.start();
        p.join();
        c.join();
        System.out.println("finish");
    }



}
